package com.tegistuff.webos.run;

import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.runners.DefaultProgramRunner;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.RunContentBuilder;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugProcessStarter;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.tegistuff.webos.AppComponent;
import com.tegistuff.webos.run.debugger.WebOSDebugProcess;
import com.tegistuff.webos.run.debugger.WebOSDebuggerProxy;
import org.jetbrains.annotations.NotNull;

/**
 * WebOSProgramRunner.java
 *
 * Copyright (C) 2011-2012 Timo Tegtmeier.
 * All rights reserved.
 */
public class WebOSProgramRunner extends DefaultProgramRunner {

	@NotNull
	public String getRunnerId() {
		return "WebOSRunner";
	}

	public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) {
		if(!( profile instanceof WebOSRunConfiguration))
            return false;
        return ((WebOSRunConfiguration) profile).getAppId() != null;
	}

    @Override
    protected RunContentDescriptor doExecute(final Project project, final Executor executor,
                                             final RunProfileState state,
                                             final RunContentDescriptor contentToReuse,
                                             final ExecutionEnvironment env) throws ExecutionException
    {
        if(!AppComponent.IsSDKSupported())
            return null;

        FileDocumentManager.getInstance().saveAllDocuments();
        RunContentDescriptor runContent;
        XDebugSession[] sessions = XDebuggerManager.getInstance(project).getDebugSessions();
        for(XDebugSession session : sessions)
            session.stop();

        if(executor.getActionName().equals("Run")) {
            ExecutionResult executionResult = state.execute(executor, this);
            if (executionResult == null) {
                return null;
            }

            onProcessStarted(env.getRunnerSettings(), executionResult);

            final RunContentBuilder contentBuilder = new RunContentBuilder(project, this, executor);
            contentBuilder.setExecutionResult(executionResult);
            contentBuilder.setEnvironment(env);

            runContent = contentBuilder.showRunContent(contentToReuse);
        } else {
            final OSProcessHandler buildProcess = ((WebOSRunningState)state).createProcessWithoutLogging();
            ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
                @Override
                public void run() {
                    ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
                    indicator.setText("Building & installing application package...");
                    indicator.setIndeterminate(true);
                    buildProcess.startNotify();
                    buildProcess.waitFor();                }
            }, "Building webOS application", false, project);
            if(buildProcess.getProcess().exitValue() != 0)
                throw new ExecutionException("The build process could not be completed.");
            
            final WebOSRunConfiguration runConfiguration = (WebOSRunConfiguration)(state.getRunnerSettings().getRunProfile());
            final WebOSDebuggerProxy debuggerProxy = new WebOSDebuggerProxy(runConfiguration);
            final OSProcessHandler logProcessHandler = runConfiguration.FollowLogs
                    ? ((WebOSRunningState)state).createLogOnlyProcess()
                    : null;
            
            final XDebugSession session = XDebuggerManager.getInstance(project).
                startSession(this, env, contentToReuse, new XDebugProcessStarter() {
                    @NotNull
                    public XDebugProcess start(@NotNull final XDebugSession session) {
                        return new WebOSDebugProcess(runConfiguration, session, debuggerProxy, logProcessHandler);
                    }
                });
            runContent = session.getRunContentDescriptor();
        }

        return runContent;
    }
}
